package com.etone.smartAudit.config;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.digest.DigestUtil;
import liquibase.pro.packaged.B;
import lombok.Data;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;

@Component
@Data
public class BNSConfig {
    /***
     * header参数名称	参数说明	是否为必填	参数类型
     * corpId	企业ID	是	String
     * appId	应用唯一编号	是	String
     * cguid	请求事务ID，需保持唯一，18位：毫秒级时间戳+5位随机数	是	String
     * mac	数据签名	是	String
     * 将corpId+appId+cguid的值拼接成字符串A，拼接时不需要插入“+”号；
     * 2、对字符串A使用B端用户在BSN平台申请的私钥进行SHA256WITHECDSA签名。
     * 例如：签名值=SHA256WITHECDSA(corpId+appId+cguid）
     */

    /***
     * 签名私钥
     */
    @Value("${bns.privateKey:MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgc1dAoH/BnHGNrj9IEdi4CY5bz2SXPcx6ygYJiYMBJeigCgYIKoZIzj0DAQehRANCAATLrhAa+uWMd6ryqn4+3ttNA5FdKOsme/XjPWFHLQN6N0lAxpZ/mJfXbNpcf0yW2RwqCp9KQQQpAOjQIdb2KFVD}")
    private String privateKey;

    @Value("${bns.corpid:110064}")
    private String corpId;

    @Value("${bns.appid:1100640000000}")
    private String appId;

    private String cguid;

    private String mac;

    /***
     * 服务返回的token
     */
    private String token;

    /***
     * 服务端鉴权
     * @return
     */
    public BNSConfig initCorpAuth() {
        this.cguid = System.currentTimeMillis() + RandomUtil.randomString(RandomUtil.BASE_NUMBER, 5);
        StringBuilder sb = new StringBuilder();
        sb.append(this.corpId).append(this.appId).append(this.cguid);
        this.mac = sign(sb.toString());
        return this;
    }

    /***
     * 能力鉴权
     * @param token
     * @return
     */
    public BNSConfig initCapacity(String token) {
        this.token = token;
        this.cguid = System.currentTimeMillis() + RandomUtil.randomString(RandomUtil.BASE_NUMBER, 5);
        StringBuilder sb = new StringBuilder();
        sb.append(this.corpId).append(this.appId).append(this.cguid).append(token);
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withECDSA, "", "");
//        this.mac = new String(sign.sign(sb.toString().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
        this.mac = sign(sb.toString());
        return this;
    }

    public byte[] base64String2Byte(String base64Str) {
        return Base64.decodeBase64(base64Str);
//        return base64Str.getBytes(StandardCharsets.UTF_8);
    }

    public String sign(String Data) {
        try {
            byte[] data = Data.getBytes();
            byte[] keyBytes = base64String2Byte(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

            KeyFactory keyFactory = KeyFactory.getInstance("EC");

            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
//            Signature signature = Signature.getInstance("SHA256withECDSA");//这个根据需求填充SHA1WithRSA或SHA256WithRSA
            Signature signature = Signature.getInstance(SignAlgorithm.SHA256withECDSA.getValue());//这个根据需求填充SHA1WithRSA或SHA256WithRSA
            signature.initSign(priKey);
            signature.update(data);
            return Base64.encodeBase64String(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
//        String key = "MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBKH4xbsrZ//1NnZAE9zOdfL3ii4YuEMHBEJcIogVeBfQ==";
//        BNSConfig bnsConfig = new BNSConfig();
//        bnsConfig.setPrivateKey(key);
//        System.out.println("bnsConfig.sign(\"ggg\") = " +bnsConfig.sign("ggg"));
        String data = DigestUtil.sha256Hex("wfefe");
        System.out.println("data = " + data);
//
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withECDSA, Base64.decodeBase64(key), null);
////        this.mac = new String(sign.sign(sb.toString().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
//        System.out.println("sign = " + sign);
//        System.out.println(sign.sign("ff".getBytes(StandardCharsets.UTF_8)));
    }

}
